home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
mg2a_src.zip
/
SYS
/
AMIGA
/
FILEIO.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-08-23
|
13KB
|
536 lines
/*
* Name: MG 2a401
* Commodore Amiga file I/O.
* Last edit: 05-May-88 swalton@solar.stanford.edu
* Next-to-Last edit: 16-Dec-87 mic@emx.utexas.edu
* Created: 23-Jul-86 mic@emx.utexas.edu
*
* Read and write ASCII files. All of the low level file I/O
* knowledge is here. Uses AmigaDOS standard I/O and does its
* own dynamic buffering; this seems to save about 2K worth
* of space in the executable image.
*/
#ifdef LATTICE
#include <string.h>
#include <exec/types.h>
#endif
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#ifdef USE_ARP
#include "libraries/arpbase.h"
#else
#define FCHARS 32L
#endif
#undef TRUE
#undef FALSE
#include "def.h"
#define NIOBUF 4096
extern ULONG Rename(), UnLock(), Close(), FreeMem();
extern LONG Write(), Read();
extern UBYTE *AllocMem();
extern struct FileLock *Lock();
extern struct FileHandle *Open();
static struct FileHandle *ffh = 0;
static UBYTE *iobuf;
static int ibufo, niobuf;
static LONG iostat, access_mode;
#ifdef MANX
extern char *strncpy(), *strncat(), *index(), *rindex();
#endif
#ifdef LATTICE
extern char *malloc() ;
#define index strchr
#define rindex strrchr
#endif
#define getch() (ibufo == niobuf) ? FillBuf() : iobuf[ibufo++]
#define putch(c) {if (niobuf == NIOBUF) FlushBuf(); iobuf[niobuf++] = c;}
/*
* Open the Emacs internal file for reading.
*/
ffropen(fn)
char *fn;
{
if ((iobuf = AllocMem((ULONG) NIOBUF, 0L)) == NULL)
return (FIOERR);
if ((ffh = Open(fn, access_mode = MODE_OLDFILE)) == 0L) {
FreeMem(iobuf, (ULONG) NIOBUF);
return (FIOFNF);
}
ibufo = niobuf = 0;
return (FIOSUC);
}
/*
* Open a file for writing. Return TRUE if all
* is well, and FALSE on error (cannot create).
*/
ffwopen(fn)
char *fn;
{
if ((iobuf = AllocMem((ULONG) NIOBUF, 0L)) == NULL)
return (FIOERR);
if ((ffh = Open(fn, access_mode = MODE_NEWFILE)) == 0L) {
ewprintf("Cannot open file for writing");
FreeMem(iobuf, (ULONG) NIOBUF);
return (FIOERR);
}
niobuf = 0;
iostat = NIOBUF; /* pretend we wrote out a full buffer last time */
return (FIOSUC);
}
/*
* Close a file, flushing the output buffer. Should look at
* the status.
*/
ffclose()
{
if (access_mode == MODE_NEWFILE)
FlushBuf();
if (ffh)
(void) Close(ffh);
if (iobuf)
FreeMem(iobuf, (ULONG) NIOBUF);
return (FIOSUC);
}
/*
* Write a buffer to the already opened file. bp points to the
* buffer. Return the status. Check only at the newline and
* end of buffer.
*/
ffputbuf(bp)
BUFFER *bp;
{
register char *cp;
register char *cpend;
register LINE *lp;
register LINE *lpend;
lpend = bp->b_linep;
lp = lforw(lpend);
do {
cp = <ext(lp)[0]; /* begining of line */
cpend = &cp[llength(lp)]; /* end of line */
while(cp != cpend)
putch(*(cp++)); /* putch only evalutes its arg once */
lp = lforw(lp);
if(lp == lpend) break; /* no implied newline on last line */
putch('\n');
} while(iostat > 0L);
if(iostat == -1L) {
ewprintf("Write I/O error");
return FIOERR;
}
return FIOSUC;
}
/*
* Read a line from a file, and store the bytes
* in the supplied buffer. Stop on end of file or end of
* line. When FIOEOF is returned, there is a valid line
* of data without the normally implied \n.
*/
ffgetline(buf, nbuf, nbytes)
register char *buf;
register int nbuf;
register int *nbytes;
{
register int c;
register int i;
i = 0;
while((c = getch())!=EOF && c!='\n') {
buf[i++] = c;
if (i >= nbuf) return FIOLONG;
}
if (c == EOF && (iostat == -1L)) {
ewprintf("File read error");
return FIOERR;
}
*nbytes = i;
return c==EOF ? FIOEOF : FIOSUC;
}
#ifndef NO_BACKUP
/*
* Rename the current file into a backup copy,
* possibly after deleting the original file.
*/
fbackupfile(fname)
char *fname;
{
struct FileLock *twiddle, *lock;
char buffer[NFILEN];
(void) strncpy(buffer,fname,NFILEN - 1);
(void) strcat(buffer,"~");
lock = Lock(fname,(ULONG)EXCLUSIVE_LOCK);/* does file exist? */
if (!lock)
return (FALSE); /* nope, return error */
twiddle = Lock(buffer,(ULONG)EXCLUSIVE_LOCK);
if (twiddle) { /* delete old backup */
UnLock(twiddle); /* let it go */
if (!DeleteFile(buffer)) {
UnLock(lock);
return (FALSE);
}
twiddle = NULL;
}
/* rename file to backup name (after unlocking the file)
*/
UnLock(lock);
return (int) Rename(fname,buffer);
}
#endif NO_BACKUP
#ifndef NO_STARTUP
/*
* Return name of user's startup file. On Amiga, make it
* .mg in the current directory, then s:.mg
*/
static char startname[] = ".mg";
static char altstartname[] = "s:.mg";
char *startupfile()
{
struct FileLock *lock;
if (lock = Lock(startname,(ULONG)SHARED_LOCK)) {
UnLock(lock);
return(startname);
}
if (lock = Lock(altstartname,(ULONG)SHARED_LOCK)) { /* alternate */
UnLock(lock);
return (altstartname);
}
return (NULL);
}
#endif NO_STARTUP
/*
* The string "fn" is a file name. Perform any required name adjustments,
* including conversion to a fully qualified path if NO_DIR isn't defined.
*/
#define MAX_ELEMS 8 /* Maximum number of elements */
extern char MyDirName[];
char *adjustname(fn)
register char *fn;
{
#ifndef NO_DIR
static char fnb[MAX_ELEMS*FCHARS + 1];
struct FileLock *lock;
long PathName();
void TackOn();
char *dup, *p;
if (!index(fn, ':')) { /* no device */
strcpy(fnb, MyDirName);
TackOn(fnb, fn);
if (!index(fn, '/')) /* completely bare name */
return fnb;
} else
strcpy(fnb, fn);
/*
* Else fn has some path components in it. We try to PathName
* the whole thing first, but since the file specified by fn
* may not exist, we PathName the leading part and TackOn the
* trailing part if it doesn't.
*/
if (lock = Lock(fnb, SHARED_LOCK)) {
if (PathName(lock, fnb, (long) MAX_ELEMS) !=0) {
UnLock(lock);
return fnb;
}
ewprintf("adjustname: PathName() failed!");
UnLock(lock);
return fn;
}
if (!(p = rindex(fnb, '/')))
p = index(fnb, ':');
p++;
strcpy((dup = malloc(strlen(p) + 1)), p);
*p = '\0';
if (lock = Lock(fnb, SHARED_LOCK)) {
if (PathName(lock, fnb, (long) MAX_ELEMS) != 0) {
UnLock(lock);
TackOn(fnb, dup);
free(dup);
return fnb;
}
ewprintf("adjustname: PathName() failed!");
UnLock(lock);
}
free(dup);
#endif
return fn; /* if all else fails */
}
/*
* Functions to read/write into the I/O buffer
*/
int FlushBuf()
{
if (niobuf > 0) {
iostat = Write(ffh, iobuf, (ULONG) niobuf);
niobuf = 0;
}
}
/*
* Fill up the input buffer and return the first character in it.
*/
int FillBuf()
{
if ((iostat = Read(ffh, iobuf, (ULONG) NIOBUF)) <= 0L)
return (EOF);
ibufo = 0;
niobuf = (int) iostat;
return (int) (iobuf[ibufo++]);
}
#ifndef NO_DIRED
#include "kbd.h"
copy(frname, toname)
char *frname, *toname;
{
#ifdef MANX
return fexecl("copy", "copy", frname, toname, (char *) 0);
#endif
#ifdef LATTICE
int error ;
if (error = forkl("copy", "copy", frname, toname, (char *) 0, (char *) 0, 2))
return error ;
return (int) wait(2) ;
#endif
}
BUFFER *dired_(dirname)
char *dirname;
{
register BUFFER *bp;
char line[256];
BUFFER *findbuffer();
char *tmpname, *mktemp();
int i;
VOID lfree();
if((dirname = adjustname(dirname)) == NULL) {
ewprintf("Bad directory name");
return NULL;
}
if(!isdirectory(dirname)) {
ewprintf("Not a directory: %s", dirname);
return NULL;
}
if((bp = findbuffer(dirname)) == NULL) {
ewprintf("Could not create buffer");
return NULL;
}
bclear(bp); /* clear out leftover garbage */
(void) strcpy(line, "list >");
(void) strncat(line, tmpname = mktemp("ram:mgXXX.XXX"), sizeof(line));
(void) strncat(line, " \"", sizeof(line));
(void) strncat(line, dirname, sizeof(line));
(void) strncat(line, "\"", sizeof(line));
Execute(line, 0L, 0L);
if (f